#!/usr/bin/env python
# $Id: test2-50.py df54dec975f4 2012/09/09 20:22:40 pgurumur $
# Copyright (c) 2009 Prabhu Gurumurthy  <pgurumur@gmail.com>
# 
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

__version__ = "$Revision: df54dec975f4 $"
__author__ = "$Author: pgurumur $"

import optparse
import os
import sys

from mercurial import commands, cmdutil, repo, ui, hg, error, util

from venya.lib import cmdparser
from venya.lib import stdlib

class QuickSilver(object):
   def __init__(self, URL, User = None):
      super(QuickSilver, self).__init__()
      self._user = None
      self._url = None
      self._dir = None
      self._ui = ui.ui()

      if User:
         self._user = User
      else:
         self._user = self._ui.username()

      if URL:
         self._url = URL

      if self._ui.has_section('paths'):
         for path in self._ui.configitems('paths'):
            if path[0] == self._url:
               self._url = path[1]
               break

      if self._url:
         self._repo = self._hgutil(self._ui, self._url)

   def _expandfiles(self, files = []):
      listFiles = []
      pwd = os.getcwd()
      for ix in files:
         temp = "%s/%s" %(pwd, ix)
         listFiles.append(temp)

      return listFiles

   def _hgutil(self, UI, Directory, Change = False):
      retval = None
      try:
         if Change and Directory and os.path.exists(Directory):
            os.chdir(Directory)
      except OSError as err:
         raise ValueError(err)

      try:
         retval = hg.repository(UI, Directory)
      except error.RepoError as err:
         raise ValueError(err)

      return retval

   def addDir(self, Directory):
      self._dir = Directory

   def checkout(self):
      try:
         if self._dir:
            commands.clone(self._ui, self._url, self._dir)
         else:
            raise ValueError("No directory given to checkout the repository")
      except error.Abort as err:
         raise ValueError(err)

   def commit(self, Message, files = []):
      opts = {}
      opts['user'] = self._user
      if Message:
         opts['message'] = stdlib.my_str(Message)
      else:
         raise ValueError("Cannot commit to repository without checkin message!")

      if len(files):
         files = self._expandfiles(files)

      if not self._dir:
         path = util.expandpath(util.urllocalpath(os.getcwd()))
         repo = self._hgutil(self._ui, cmdutil.findrepo(path))

      if self._url:
         if Message:
            commands.commit(self._ui, repo, *files, **opts)

         commands.push(self._ui, repo, self._url)
      else:
         raise ValueError("Cannot proceed to commit without hg/mercurial URL")

   def update(self):
      if self._url:
         repo = None
         if self._dir:
            repo = self._hgutil(self._ui, self._dir)
         else:
            path = util.expandpath(util.urllocalpath(os.getcwd()))
            repo = self._hgutil(self._ui, cmdutil.findrepo(path))

         commands.pull(self._ui, repo, self._url)
         commands.update(self._ui, repo)
      else:
         raise ValueError("Cannot proceed to update without hg/mercurial URL")

   def add(self, files = []):
      if len(files):
         files = self._expandfiles(files)

      if not self._dir:
         path = util.expandpath(util.urllocalpath(os.getcwd()))
         repo = self._hgutil(self._ui, cmdutil.findrepo(path))

      if len(files):
         commands.add(self._ui, repo, *files)

   def summary(self):
      repo = None
      if self._dir:
         repo = self._hgutil(self._ui, self._dir)
      else:
         path = util.expandpath(util.urllocalpath(os.getcwd()))
         repo = self._hgutil(self._ui, cmdutil.findrepo(path))

      commands.summary(self._ui, repo)

class vermilion(cmdparser.GetOpt):
   option_list = (
         optparse.make_option("-u", "--url", type = "str",
            help = "Mercurial URL", dest = "url"),
         optparse.make_option("-U", "--user", type = "str",
            help = "Username to use for mercurial repository", dest = "user"),
         optparse.make_option("-d", "--directory", type = "str",
            help = "Directory to use for the repository", dest = "directory"),
         optparse.make_option("-m", "--message", type = "str",
            help = "Checkin message from the commandline", dest = "message"),
   ) + cmdparser.GetOpt.option_list

   usage = "commands [ options ] [ files ]"

   def __init__(self, **kwargs):
      super(vermilion, self).__init__(**kwargs)
      self._hg = None

   def scmhelp(self):
      self.printhelp()
      print
      print "%s commands" %str(self)
      print "\tcommit | ci   [ Checkin/commit the change to repository ]"
      print "\tcheckout | co [ Checkout from the repository ]"
      print "\tupdate | up   [ Sync changes from repository ]"
      print "\tadd | include [ Add files/directory to the repository ]"
      print "\tsum | summary [ print directory summary ]"
      print "\thelp | ?      [ prints this help ]"

   def handle(self):
      (options, args) = self.parse()
      command = None
      try:
         command = args[1]
      except IndexError:
         self.scmhelp()
         self.error("Need command to proceed!")

      files = []
      try:
         files = args[2:]
      except IndexError:
         pass

      if command in ('help', '?'):
         self.scmhelp()
      else:
         try:
            self._hg = QuickSilver(options.url)
            self._hg.addDir(options.directory)
            if command in ('commit', 'ci'):
               self._hg.commit(options.message, files)
            elif command in ('checkout', 'co'):
               self._hg.checkout()
            elif command in ('update', 'up'):
               self._hg.update()
            elif command in ('add', 'include'):
               self._hg.add(files)
            elif command in ('sum', 'summary'):
               self._hg.summary()
            else:
               self.scmhelp()
               self.error("Invalid command %s" %command)
         except ValueError as err:
            self.error(err)

if __name__ == "__main__":
   scm = None
   try:
      scm = vermilion(version = 1.0, args = sys.argv)
      if len(scm) <= 1:
         scm.printhelp()
      else:
         scm.handle()
   except cmdparser.GetOptError as err:
      print(err)
      sys.exit(1)
